package com.market.xg.gateway.filter;

import com.auth0.jwt.interfaces.Claim;
import com.market.xg.common.starter.auth.XgAppUser;
import com.market.xg.common.starter.constant.XgHeaderConstant;
import com.market.xg.common.starter.util.CommonUtils;
import com.market.xg.common.starter.util.JsonUtils;
import com.market.xg.common.starter.util.JwtUtil;
import com.market.xg.gateway.conf.AuthProperties;
// import com.market.xg.gateway.gray.GrayLoadBalancer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.net.URLEncoder;
import java.util.Map;

@Slf4j
@Component
public class AuthFilter implements GlobalFilter, Ordered {

  @Autowired AuthProperties authProperties;

  @Autowired JwtUtil jwtUtil;

  @Override
  public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
    String path = exchange.getRequest().getURI().getPath();
    log.info("AuthFilter filter path={}", path);
    if (authProperties.isBlackUri(path)) {
      log.info("AuthFilter filter isBlackUri");
      return Mono.empty();
    }
    String appGeneralToken =
        exchange.getRequest().getHeaders().getFirst(XgHeaderConstant.XG_APP_GENERAL_TOKEN);
    String pcGeneralToken =
        exchange.getRequest().getHeaders().getFirst(XgHeaderConstant.XG_PC_GENERAL_TOKEN);
    String appManagerToken =
        exchange.getRequest().getHeaders().getFirst(XgHeaderConstant.XG_APP_MANAGER_TOKEN);
    String pcManagerToken =
        exchange.getRequest().getHeaders().getFirst(XgHeaderConstant.XG_PC_MANAGER_TOKEN);
    // 解析出jwt 对应的token
    Map<String, Claim> claimMap = null;
    if (CommonUtils.isNotEmpty(appGeneralToken)) {
      claimMap = jwtUtil.decryptToken(appGeneralToken);
    } else if (CommonUtils.isNotEmpty(pcGeneralToken)) {
      claimMap = jwtUtil.decryptToken(appGeneralToken);
    } else if (CommonUtils.isNotEmpty(appManagerToken)) {
      claimMap = jwtUtil.decryptToken(appGeneralToken);
    } else if (CommonUtils.isNotEmpty(pcManagerToken)) {
      claimMap = jwtUtil.decryptToken(appGeneralToken);
    } else {
      // 查看路径是否注册、登录路径
      return chain.filter(exchange);
    }
    Claim claim = claimMap.get("xgAppUser");
    XgAppUser xgAppUser = JsonUtils.deserialize(claim.asString(), XgAppUser.class);
    return chain.filter(
        exchange
            .mutate()
            .request(
                exchange
                    .getRequest()
                    .mutate()
                    .headers(
                        httpHeaders -> {
                          try {
                            httpHeaders.set(
                                "xgAppUser",
                                URLEncoder.encode(JsonUtils.serialize(xgAppUser), "UTF-8"));
                          } catch (Exception e) {
                            log.error("httpHeadersError", e);
                          }
                        })
                    .build())
            .build());
  }

  @Override
  public int getOrder() {
    return -99;
  }

  //  /***
  //   * 调用GrayLoadBalancer的choose()方法，获取不同服务实例
  //   * @return
  //   * //     */
  //  public Mono<Response<ServiceInstance>> choose(ServerWebExchange exchange) {
  //    //        URI uri = exchange.getRequest().getURI();
  //    // 获取URI，URI中包含了要调用的服务集群集合信息，我们需要把它传到GrayLoadBalancer中
  //    // 在GrayLoadBalancer中可以根据集合进行筛选
  //    Route route = exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR);
  //    log.info("AuthFilter choose route={}", route);
  //    URI uri = route.getUri();
  //    log.info("AuthFilter filter uri={}", uri);
  //    String getHost = uri.getHost();
  //    log.info("AuthFilter filter getHost={}", getHost);
  //    GrayLoadBalancer grayLoadBalancer =
  //        new GrayLoadBalancer(
  //            // 用工厂对象加载可用的服务列表
  //            clientFactory.getLazyProvider(uri.getHost(), ServiceInstanceListSupplier.class),
  //            uri.getHost());
  //    if (grayLoadBalancer == null) {
  //      throw new RuntimeException("没有找到可用的实例对象");
  //    }
  //
  //    // 因为会有根据版本信息或者用户身份信息或者IP实现,我们可以把请求头信息封装到Request中
  //    HttpHeaders headers = exchange.getRequest().getHeaders();
  //    // 调用GrayLoadBalancer的choose()获取实例
  //    return grayLoadBalancer.choose(new DefaultRequest<HttpHeaders>(headers));
  //  }
  //  /****
  //   * 封装灰度实例地址信息（将 http://car-version1/car 换成 http://192.168.23.1:18082/car）
  //   */
  //  public Mono<Response<ServiceInstance>> setInstanceInfo(
  //      Mono<Response<ServiceInstance>> responseInstance,
  //      ServerWebExchange exchange,
  //      String schemePrefix) {
  //    return responseInstance.doOnNext(
  //        (response) -> {
  //          if (response.hasServer()) {
  //            URI url = exchange.getRequest().getURI();
  //            String overrideScheme = null;
  //            if (schemePrefix != null) {
  //              overrideScheme = url.getScheme();
  //            }
  //
  //            DelegatingServiceInstance serviceInstance =
  //                new DelegatingServiceInstance(
  //                    (ServiceInstance) response.getServer(), overrideScheme);
  //            URI requestURI = LoadBalancerUriTools.reconstructURI(serviceInstance, url);
  //            if (log.isTraceEnabled()) {
  //              log.trace("LoadBalancerClientFilter url chosen: " + requestURI);
  //            }
  //
  //            exchange
  //                .getAttributes()
  //                .put(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR, requestURI);
  //          }
  //        });
  //  }
}
